import { defineConfig, loadEnv } from 'vite'
import type { UserConfig, ConfigEnv } from 'vite'
import { fileURLToPath } from 'url'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { viteMockServe } from 'vite-plugin-mock'
import { createHtmlPlugin } from 'vite-plugin-html'

// 依赖引入
import AutoImport from 'unplugin-auto-import/vite'
import Icons from 'unplugin-icons/vite'
import Components from 'unplugin-vue-components/vite'
import IconsResolver from 'unplugin-icons/resolver'
import ElementPlus from 'unplugin-element-plus/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
    // 获取当前工作目录
    const root = process.cwd()
    // 获取环境变量
    const env = loadEnv(mode, root)
    return {
        // 项目根目录
        root,
        // 项目部署的基础路径
        base: '/',
        publicDir: fileURLToPath(new URL('./public', import.meta.url)), // 无需处理的静态资源位置
        assetsInclude: fileURLToPath(new URL('./src/assets', import.meta.url)), // 需要处理的静态资源位置
        plugins: [
            // Vue模板文件编译插件
            vue(),
            // jsx文件编译插件
            vueJsx(),
            viteMockServe({
                // 如果接口为 /mock/xxx 以 mock 开头就会被拦截响应配置的内容
                mockPath: 'mock', // 数据模拟需要拦截的请求起始 URL
                localEnabled: true, // 本地开发是否启用
                prodEnabled: false // 生产环境不开启
            }),
            // 开启ElementPlus自动引入CSS
            ElementPlus({}),
            // 自动引入组件及ICON
            AutoImport({
                // 定义需要自动引入的框架，涉及以下三个包的变量不需要再导入
                imports: ['vue', 'vue-router', 'pinia'],
                // 处理eslint，提示错误问题
                eslintrc: {
                    enabled: true
                },
                // 自动解析加载器
                resolvers: [IconsResolver(), ElementPlusResolver()],
                // dts指定配置类型文件的位置，如果不配置则根目录有 auto-imports.d.ts 文件
                dts: fileURLToPath(new URL('./types/auto-imports.d.ts', import.meta.url))
            }),
            // 自动注册组件
            Components({
                resolvers: [IconsResolver(), ElementPlusResolver()],
                // dts指定配置类型文件的位置，如果不配置则根目录有 components.d.ts 文件
                dts: fileURLToPath(new URL('./types/components.d.ts', import.meta.url)),
                // 当使用某个组件没有显示导入则以下这个目录下查找可以自动导入
                dirs: [fileURLToPath(new URL('./src/components/auto', import.meta.url))]
            }),
            // 自动安装图标
            Icons({
                autoInstall: true
            }),
            // html-plugin插件的配置
            createHtmlPlugin({
                // 注入到模板中的资源
                inject: {
                    data: {
                        monentscript: '<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/min/moment.js"></script>',
                        videoscript: '<script src="https://cdn.jsdelivr.net/npm/video.js@7.14.3/dist/video.min.js"></script>',
                        echartscript: '<script src="https://cdn.jsdelivr.net/npm/echarts@5.2.1/echarts"></script>',
                        jspdfscript: '<script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/pdf.js"></script>',
                        xlsxscript: '<script src="https://cdn.jsdelivr.net/npm/xlsx@0.17.4/dist/xlsx.full.min.js"></script>'
                    }
                }
            })
        ],
        // 运行后本地预览的服务器
        server: {
            // 是否开启https
            // @ts-ignore
            https: false,
            // 指定服务器应该监听哪个 IP 地址。 如果将此设置为 0.0.0.0 或者 true 将监听所有地址，包括局域网和公网地址。
            host: true,
            // 开发环境预览服务器端口
            port: 3000,
            // 启动后是否自动打开浏览器
            open: false,
            // 是否开启CORS跨域
            cors: true,
            // 代理服务器
            // 帮助我们开发时解决跨域问题
            proxy: {
                // 这里的意思是 以/api开头发送的请求都会被转发到 http://xxx:3000
                '/api': {
                    target: 'http://xxx:9000',
                    // 改变 Host Header
                    changeOrigin: true,
                    // 发起请求时将 '/api' 替换为 ''
                    rewrite: path => path.replace(/^\/api/, '')
                }
            }
        },
        // 打包配置
        build: {
            // 关闭 sorcemap 报错不会映射到源码
            sourcemap: false,
            // 打包大小超出 400kb 提示警告
            chunkSizeWarningLimit: 400,
            rollupOptions: {
                // 打包入口文件 根目录下的 index.html
                // 也就是项目从哪个文件开始打包
                input: {
                    index: fileURLToPath(new URL('./index.html', import.meta.url))
                },
                // 打包排除项
                external: ['moment', 'video.js', 'jspdf', 'xlsx', 'echart'],
                // 摇树优化（名词解释：构建过程中消除 JavaScript 上下文中未引用的代码的技术，这有助于减小最终打包文件的大小）
                treeshake: {
                    preset: 'recommended' //  Vite 摇树优化的规则： 推荐版
                },
                // 静态资源分类打包
                output: {
                    format: 'esm',
                    chunkFileNames: 'static/js/[name]-[hash].js', // 代码分割后文件名
                    entryFileNames: 'static/js/[name]-[hash].js', // 入口文件名
                    assetFileNames: 'static/[ext]/[name]-[hash].[ext]' // 静态资源文件名
                }
            }
        },
        // 配置别名
        resolve: {
            alias: {
                '@': fileURLToPath(new URL('./src', import.meta.url)),
                '#': fileURLToPath(new URL('./types', import.meta.url))
            }
        }
    }
})
